from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import Optional
import logging

from app.services.json_auth_service import JSONAuthService
from app.services.json_task_service import JSONTaskService
from app.services.crawl_service import MockCrawlService

logger = logging.getLogger(__name__)

# Security
security = HTTPBearer()

# Service instances
auth_service = JSONAuthService()

def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(security)
) -> dict:
    """获取当前用户"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )

    try:
        # 验证令牌
        payload = auth_service.verify_token(credentials.credentials, "access")
        if payload is None:
            raise credentials_exception

        user_id: str = payload.get("sub")
        if user_id is None:
            raise credentials_exception

        # 获取用户信息
        user = auth_service.get_user_by_id(user_id)
        if user is None:
            raise credentials_exception

        return user

    except Exception as e:
        logger.error(f"Authentication error: {e}")
        raise credentials_exception

async def get_current_user_ws(
    websocket: WebSocket,
    token: str,
    db: AsyncSession = Depends(get_db_session)
) -> User:
    """WebSocket认证 - 获取当前用户"""
    try:
        # 验证令牌
        payload = auth_service.verify_token(token, "access")
        if payload is None:
            await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        
        user_id: str = payload.get("sub")
        if user_id is None:
            await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        
        # 获取用户信息
        user = await auth_service.get_user_by_id(user_id, db)
        if user is None:
            await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        
        return user
        
    except Exception as e:
        logger.error(f"WebSocket authentication error: {e}")
        await websocket.close(code=status.WS_1008_POLICY_VIOLATION)
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

def require_permission(permission: str):
    """权限检查装饰器"""
    def permission_checker(user: User = Depends(get_current_user)):
        # 简单的权限检查 - 可以根据需要扩展
        if user.role == "admin":
            return user  # 管理员拥有所有权限
        
        # 根据权限类型检查
        if permission == "task:create" and user.role in ["user", "admin"]:
            return user
        elif permission == "task:delete" and user.role in ["user", "admin"]:
            return user
        elif permission == "system:manage" and user.role == "admin":
            return user
        else:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail=f"Permission '{permission}' required"
            )
    
    return permission_checker

def get_auth_service() -> JSONAuthService:
    """获取认证服务实例"""
    return auth_service

def get_crawl_service() -> MockCrawlService:
    """获取爬虫服务实例"""
    return MockCrawlService()

def get_task_service() -> JSONTaskService:
    """获取任务服务实例"""
    return JSONTaskService()

# Optional dependencies for specific endpoints
async def get_optional_user(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
    db: AsyncSession = Depends(get_db_session)
) -> Optional[User]:
    """获取可选的当前用户（用于公开接口）"""
    if not credentials:
        return None
    
    try:
        payload = auth_service.verify_token(credentials.credentials, "access")
        if payload is None:
            return None
        
        user_id: str = payload.get("sub")
        if user_id is None:
            return None
        
        user = await auth_service.get_user_by_id(user_id, db)
        return user
        
    except Exception as e:
        logger.error(f"Optional authentication error: {e}")
        return None

def validate_admin_user(user: User = Depends(get_current_user)) -> User:
    """验证管理员用户"""
    if user.role != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Admin privileges required"
        )
    return user
